package com.rockbb.common.sso.session;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.rockbb.common.utilities.security.StringDigest;

public class HashMapSessionMap implements SessionMap 
{
	private static Logger logger = Logger.getLogger(HashMapSessionMap.class);
	private Map<String, Session> sessions;

	public void initialise() {
		sessions = new HashMap<String, Session>();
	}

	public void reset()
	{
		sessions.clear();
	}

	public Session get(String sid) {
		return sessions.get(sid);
	}

	public Collection<String> getKeys() {
		return sessions.keySet();
	}

	public List<Session> getSessions(Collection<String> keysList)
	{
		logger.debug("get sessions with " + keysList.size() + " keys");
		List<Session> output = new ArrayList<Session>();
		if (keysList != null && keysList.size() > 0)
		{
			for (String key : keysList)
			{
				Session session = sessions.get(key);
				if (session != null) output.add(session);
			}
		}
		logger.debug("returned " + output.size() + " sessions");
		return output;
	}

	public void remove(String sid) {
		sessions.remove(sid);
	}

	public void put(String sid, Session session) {
		sessions.put(sid, session);
	}

	public int size() {
		return sessions.size();
	}

	public Session createSession(long uuid, String browser, String ip, boolean persistent)
	{
		Session session = new Session();
		session.setSession_uuid(uuid);
		session.setSession_start(System.currentTimeMillis());
		session.setSession_time(System.currentTimeMillis());
		session.setSession_ip(ip);
		session.setSession_secure(0);
		session.setSession_browser(browser);
		session.setSession_autologin(SessionConstants.SESSION_AUTOLOGIN_OFF);
		session.setSession_token(StringDigest.unique_id());
		if (persistent)
		{
			put(session.getSession_id(), session);
		}
		return session;
	}

	public void expireSession(String sid)
	{
		Session session = get(sid);
		if (session != null)
		{
			session.setSession_time(session.getSession_time() - SessionConstants.SESSION_EXPIRE_MAX*1000);
		}
	}

	public void renewSession(String sid, String ip)
	{
		Session session = get(sid);
		if (session != null)
		{
			session.setSession_time(System.currentTimeMillis());
			session.setSession_ip(ip);
		}
	}

	public void updateSessionUser(String sid, long uuid, int autologin)
	{
		Session session = get(sid);
		if (session != null)
		{
			session.setSession_time(System.currentTimeMillis());
			session.setSession_uuid(uuid);
			session.setSession_autologin(autologin);
		}
	}

	public void resetSession(String sid)
	{
		Session session = get(sid);
		if (session != null)
		{
			session.setSession_uuid(SessionConstants.USER_UID_ANONYMOUS);
			session.setSession_start(System.currentTimeMillis());
			session.setSession_time(System.currentTimeMillis());
			session.setSession_secure(0);
			session.setSession_autologin(SessionConstants.SESSION_AUTOLOGIN_OFF);
			session.setSession_token(StringDigest.unique_id());
		}
	}

	public void resetSessionToken(String sid)
	{
		Session session = get(sid);
		if (session != null)
		{
			session.setSession_time(System.currentTimeMillis());
			session.setSession_token(StringDigest.unique_id());
		}
	}

	public int cleanUp()
	{
		List<String> expired = new ArrayList<String>();
		Iterator<Session> iter = sessions.values().iterator();
		while (iter.hasNext()) {
			Session session = iter.next();
		    if (session.is_expired()) {
		    	expired.add(session.getSession_id());
		    }
		}
		int cleaned = expired.size();
		for (int i=0; i<cleaned; i++) {
			remove(expired.get(i));
		}
		expired.clear();
		expired = null;
		logger.info("Sessions: " + sessions.size() + " cleaned: " + cleaned);
		return cleaned;
	}
}
